#include "../import/head.h"
#include "proc_misc.h"
#include "../data_struct/head.h"
#include "../global/head.h"
#include "../macro/head.h"
#include "../msg/head.h"
#include "../helper_package/head.h"
#include "../helper_heart/head.h"
#include "../helper_http/head.h"
#include "../helper_net/head.h"
#include "../helper_tcp/head.h"
#include "../helper_udp/head.h"
#include "../helper_odbc/head.h"

namespace xos_sgsj
{

    proc_misc::proc_misc()
    {
    }

    proc_misc::~proc_misc()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int proc_misc::proc( data * pData )
    {
        int ret = 0;

        int nMsg = pData->m_nMsg;

        switch( nMsg )
        {
            // program msg
            case MSG_START_PROGRAM:
                {
                    ret = init_load_db();
                }
                break;
            case MSG_DB_INIT_LOADED:
                {
                    ret = on_db_init_loaded( pData );
                }
                break;
            case MSG_HTTP_SERVER_STARTED:
                {
                    ret = on_start_http( pData );
                }
                break;
            case MSG_TCP_SERVER_STARTED:
                {
                    ret = on_start_tcp( pData );
                }
                break;
            case MSG_UDP_SERVER_STARTED:
                {
                    ret = on_start_udp( pData );
                }
                break;
            case MSG_PROGRAM_STARTED:
                {
                    ret = on_program_started();
                }
                break;
            case MSG_QUITING:
                {
                    g_pSysData->m_bQuiting = true;
                    ret = stop_net();
                }
                break;
            case MSG_NET_STOPPED:
                {
                    ret = post_quitted();
                }
                break;
            case MSG_QUITED:
                {
                    g_pSysData->m_bQuit = true;
                    LOG3( "quit" );
                }
                break;
            default:
                {
                    ret = 1;
                }
                break;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

	int proc_misc::on_db_init_loaded( data * pData )
	{
		int ret = 0;

		if( pData->m_bSuccess )
		{
			ret = start_http();
		}
		else
		{
			LOG4( "init load db failed" );
			ret = post_quitting();
		}

		return ret;
	}

	int proc_misc::init_load_db()
	{
		int ret = 0;

		helper_odbc obj;
		ret = obj.init_load( 0 );

		return ret;
	}

    int proc_misc::on_start_http( data * pData )
    {
        int ret = 0;

        if( pData->m_bSuccess )
        {
            ret = start_tcp();
        }
        else
        {
            LOG4( "start http server failed" );
            ret = post_quitting();
        }

        return ret;
    }

    int proc_misc::start_http()
    {
        int ret = 0;

        session * pSession = 0;
        tcp * pTcp = 0;

        if( 0 == ret )
        {
            pSession = g_pSysData->m_pPool->m_session_pool.GetItem();
            pSession->init();
            pSession->m_eType = session::TYPE_HTTP_LISTEN;
        }

        if( 0 == ret )
        {
            pTcp = g_pSysData->m_pPool->m_tcp_pool.GetItem();
            pTcp->init();
        }

        if( 0 == ret )
        {
            pTcp->m_pSession = pSession;
            pSession->m_pTcp = pTcp;
            g_pSysData->m_os.m_pCrt->strcpy( pTcp->m_szIp, "" );
            pTcp->m_nPort = g_pSysData->m_config.http_server_port;
            net_tcp obj;
            ret = obj.tcp_init( pTcp );
            pSession = 0;
            pTcp = 0;
        }

        if( pSession )
        {
            pSession->release();
            pSession = 0;
        }

        if( pTcp )
        {
            pTcp->release();
            pTcp = 0;
        }

        return ret;
    }

    int proc_misc::on_start_tcp( data * pData )
    {
        int ret = 0;

        if( pData->m_bSuccess )
        {
            ret = start_udp();
        }
        else
        {
            LOG4( "start tcp server failed" );
            ret = post_quitting();
        }

        return ret;
    }

    int proc_misc::start_tcp()
    {
        int ret = 0;

        session * pSession = 0;
        tcp * pTcp = 0;

        if( 0 == ret )
        {
            pSession = g_pSysData->m_pPool->m_session_pool.GetItem();
            pSession->init();
            pSession->m_eType = session::TYPE_TCP_LISTEN;
        }

        if( 0 == ret )
        {
            pTcp = g_pSysData->m_pPool->m_tcp_pool.GetItem();
            pTcp->init();
        }

        if( 0 == ret )
        {
            pTcp->m_pSession = pSession;
            pSession->m_pTcp = pTcp;
            g_pSysData->m_os.m_pCrt->strcpy( pTcp->m_szIp, "" );
            pTcp->m_nPort = g_pSysData->m_config.tcp_server_port;
            net_tcp obj;
            ret = obj.tcp_init( pTcp );
            pSession = 0;
            pTcp = 0;
        }

        if( pSession )
        {
            pSession->release();
            pSession = 0;
        }

        if( pTcp )
        {
            pTcp->release();
            pTcp = 0;
        }

        return ret;
    }

    int proc_misc::on_start_udp( data * pData )
    {
        int ret = 0;

        if( pData->m_bSuccess )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_nMsg = MSG_PROGRAM_STARTED;
            g_pSysData->m_pImpl->notify( p );
        }
        else
        {
            LOG4( "start udp server failed" );
            ret = post_quitting();
        }

        return ret;
    }

    int proc_misc::start_udp()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_UDP_SERVER_STARTED;
        p->m_bSuccess = true;
        g_pSysData->m_pImpl->notify( p );

        return ret;
    }

    int proc_misc::on_program_started()
    {
        int ret = 0;

        if( 0 == ret )
        {
            g_pSysData->m_bIsRunning = true;
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int proc_misc::stop_net()
    {
        int ret = 0;

        session::LIST & s_list = g_pSysData->m_pPool->m_session_list;
        int nCloseNum = 0;

        for( session * p = s_list.begin(); ( 0 == ret ) && ( p != s_list.end() ); p = p->m_pNext )
        {
            p->sub_ref( 1 );
            nCloseNum++;
        }

        if( 0 == nCloseNum )
        {
            data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
            p->init();
            p->m_nMsg = MSG_NET_STOPPED;
            g_pSysData->m_pImpl->notify( p );
        }

        return ret;
    }

    int proc_misc::post_quitting()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_QUITING;
        g_pSysData->m_pImpl->notify( p );

        return ret;
    }

    int proc_misc::post_quitted()
    {
        int ret = 0;

        data * p = g_pSysData->m_pPool->m_data_pool.GetItem();
        p->init();
        p->m_nMsg = MSG_QUITED;
        g_pSysData->m_pImpl->notify( p );

        return ret;
    }

} // xos_sgsj
